import redis
import time
import configparser
from redis.exceptions import ConnectionError, TimeoutError
from public import mconfig,singletone


# 读取redis配置
REDIS_HOST = mconfig.get("redis","redis_host")
REDIS_PORT = int(mconfig.get("redis","redis_port") or 6379)
REDIS_PSWD = mconfig.get("redis","redis_pswd")
REDIS_DB = int(mconfig.get("redis","redis_db") or 256)

REDIS_TASK_LIST_KEY = mconfig.get("redis-key","task_list")
REDIS_ERROR_TASK_LIST_KEY = mconfig.get("redis-key","error_task_key")


import redis
import time
import configparser
from redis.exceptions import ConnectionError, TimeoutError

@singletone
class RedisClient(redis.Redis):
    def __init__(self):
        self.retries = 3
        self.base_delay = 1
        super().__init__(connection_pool=self._create_pool())

    def _create_pool(self):
        return redis.ConnectionPool(
            host=REDIS_HOST,
            port=REDIS_PORT,
            password=REDIS_PSWD,
            db=REDIS_DB,
            decode_responses=True
        )

    def _reconnect(self):
        for attempt in range(self.retries):
            try:
                self.connection_pool = self._create_pool()
                if self.ping():
                    return True
            except (ConnectionError, TimeoutError):
                time.sleep(self.base_delay * (2 ** attempt))
        raise ConnectionError("Redis connection failed after retries")

    def safe_get(self, key):
        try:
            return self.get(key)
        except (ConnectionError, TimeoutError):
            self._reconnect()
            return self.get(key)

    def safe_set(self, key, value, ex=None):
        try:
            return self.set(key, value, ex=ex)
        except (ConnectionError, TimeoutError):
            self._reconnect()
            return self.set(key, value, ex=ex)

    def safe_rpush(self, key, *values, ex=None):
        try:
            result = self.rpush(key, *values)
            if ex is not None:
                self.expire(key, ex)
            return result
        except (ConnectionError, TimeoutError):
            self._reconnect()
            result = self.rpush(key, *values)
            if ex is not None:
                self.expire(key, ex)
            return result

    def safe_lpop(self, key, ex=None):
        try:
            result = self.lpop(key)
            if ex is not None:
                self.expire(key, ex)
            return result
        except (ConnectionError, TimeoutError):
            self._reconnect()
            result = self.lpop(key)
            if ex is not None:
                self.expire(key, ex)
            return result

    def safe_rpop(self, key, ex=None):
        try:
            result = self.rpop(key)
            if ex is not None:
                self.expire(key, ex)
            return result
        except (ConnectionError, TimeoutError):
            self._reconnect()
            result = self.rpop(key)
            if ex is not None:
                self.expire(key, ex)
            return result

    def safe_delete(self, *keys):
        try:
            return self.delete(*keys)
        except (ConnectionError, TimeoutError):
            self._reconnect()
            return self.delete(*keys)

    def check_connection(self):
        try:
            return self.ping()
        except (ConnectionError, TimeoutError):
            return False